﻿using System;
using AutoMapper;
using Framework.Exceptions;
using Interfaces.BusinessLogic;
using Interfaces.Models;
using Interfaces.Repositories;
using Interfaces.RepositoryModels.InternalModels.UserRoleModels;
using Interfaces.Validation;

namespace BusinessLogic.Services.Operations
{
    public class SessionOperationService : ISessionOperationService
    {
        private readonly ISessionRepository _sessionRepository;
        private readonly IUserRepository _userRepository;
        private readonly IValidator _validator;
        
        public SessionOperationService(ISessionRepository sessionRepository,
            IUserRepository userRepository, IValidator validator)
        {
            _sessionRepository = sessionRepository;
            _userRepository = userRepository;
            _validator = validator;
        }

        public ISession Create(IUser user)
        {
            try
            {
                var userRepo = _userRepository.GetById(user.Id);
                if (userRepo != null)
                {
                    var model = new SessionModel
                    {
                        ChangedDate = DateTime.Now,
                        CreatedDate = DateTime.Now,
                        Id = Guid.NewGuid(),
                        User = userRepo
                    };
                    _sessionRepository.Create(model);
                    return Mapper.DynamicMap<SessionModel, ISession>(model);
                }
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }
           
            return null;
        }

        public ISession GetActiveSession(Guid userId)
        {
            try
            {
                var lastSession = _sessionRepository.GetByUserId(userId);
                if (lastSession != null)
                {
                    var session = Mapper.DynamicMap<SessionModel, ISession>(lastSession);
                    if (_validator.Validate(session).IsValid)
                        return session;
                    _sessionRepository.Delete(lastSession);
                    return null;
                }
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }
        
            return null;
        }

        public ISession GetSession(Guid sessionId)
        {
            ISession logicSession = null;
            
            try
            {
                var session = _sessionRepository.GetById(sessionId);
                if(session != null)
                     logicSession = Mapper.DynamicMap<SessionModel, ISession>(session);
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }

            return logicSession;

        }

        public IValidationResult Validate(ISession session)
        {
            IValidationResult result = null;
            try
            {
               result = _validator.Validate(session);
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }

            return result;
        }

        public void Remove(Guid sessionId)
        {
            try
            {
                _sessionRepository.Delete(sessionId);
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }
            
        }
        
        public void LastActivity(Guid sessionId)
        {
            try
            {
                var session = _sessionRepository.GetById(sessionId);
                if (session != null)
                    session.ChangedDate = DateTime.Now;
                _sessionRepository.Update(session);
            }
            catch (Exception exception)
            {
                if (ExceptionHandlingManager.HandleException(exception, PolicyNames.DALPolicy))
                    throw;
            }
           
        }

       
    }
}
